bitkeeper revision 1.1108.1.16 (41010e2br7ouRoQI0b4MbAxS1GzgpA)
authormjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Fri, 23 Jul 2004 13:10:03 +0000 (13:10 +0000)
committermjw@wray-m-3.hpl.hp.com <mjw@wray-m-3.hpl.hp.com>
Fri, 23 Jul 2004 13:10:03 +0000 (13:10 +0000)
Allow specification of the domain id to use for a new domain.

tools/libxc/xc_domain.c
tools/python/xen/lowlevel/xc/xc.c
xen/common/dom0_ops.c
xen/include/hypervisor-ifs/dom0_ops.h

index ab83d0ce7bc6328e087a96f77e839e9b8fa725e8..838418e0b72656be45842b78b955788254ee3fd2 100644 (file)
@@ -18,6 +18,7 @@ int xc_domain_create(int xc_handle,
     dom0_op_t op;
 
     op.cmd = DOM0_CREATEDOMAIN;
+    op.u.createdomain.domain = (domid_t)*pdomid;
     op.u.createdomain.memory_kb = mem_kb;
     strncpy(op.u.createdomain.name, name, MAX_DOMAIN_NAME);
     op.u.createdomain.name[MAX_DOMAIN_NAME-1] = '\0';
index 3ee75db7da4986b978219ba0d1f1850c9f6e8df4..6e55853360c931bdc0d1a2417011f9f3bed6f271 100644 (file)
@@ -44,13 +44,13 @@ static PyObject *pyxc_domain_create(PyObject *self,
     unsigned int mem_kb = 0;
     char        *name   = "(anon)";
     int          cpu = -1;
-    u32          dom;
+    u32          dom = 0;
     int          ret;
 
-    static char *kwd_list[] = { "mem_kb", "name", "cpu", NULL };
+    static char *kwd_list[] = { "dom", "mem_kb", "name", "cpu", NULL };
 
-    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|isi", kwd_list, 
-                                      &mem_kb, &name, &cpu) )
+    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iisi", kwd_list, 
+                                      &dom, &mem_kb, &name, &cpu) )
         return NULL;
 
     if ( (ret = xc_domain_create(xc->xc_handle, mem_kb, name, cpu, &dom)) < 0 )
@@ -927,6 +927,7 @@ static PyMethodDef pyxc_methods[] = {
       (PyCFunction)pyxc_domain_create, 
       METH_VARARGS | METH_KEYWORDS, "\n"
       "Create a new domain.\n"
+      " dom    [int, 0]:        Domain identifier to use (allocated if zero).\n"
       " mem_kb [int, 0]:        Memory allocation, in kilobytes.\n"
       " name   [str, '(anon)']: Informative textual name.\n\n"
       "Returns: [int] new domain identifier; -1 on error.\n" },
index 3af08f07314d86bd7cb48ef73e5c761be558f60d..c1f54869088826a729af3c985432f29f8272fe69 100644 (file)
@@ -27,6 +27,98 @@ extern unsigned int alloc_new_dom_mem(struct domain *, unsigned int);
 extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op);
 extern void arch_getdomaininfo_ctxt(struct domain *, full_execution_context_t *);
 
+static inline int is_free_domid(domid_t dom)
+{
+    struct domain  *d;
+
+    if (dom >= DOMID_SELF) return 0;
+    d = find_domain_by_id(dom);
+    if (d == NULL) {
+        return 1;
+    } else {
+        put_domain(d);
+        return 0;
+    }
+}
+
+/** Allocate a free domain id. We try to reuse domain ids in a fairly low range,
+ * only expanding the range when there are no free domain ids. This is to
+ * keep domain ids in a range depending on the number that exist simultaneously,
+ * rather than incrementing domain ids in the full 32-bit range.
+ */
+static int allocate_domid(domid_t *pdom)
+{
+    static spinlock_t domid_lock = SPIN_LOCK_UNLOCKED;
+    static domid_t curdom = 0;
+    static domid_t topdom = 101;
+    int err = 0;
+    domid_t cur, dom, top;
+
+    /* Try to use a domain id in the range 0..topdom, starting at curdom. */
+    spin_lock(&domid_lock);
+    cur = curdom;
+    dom = curdom;
+    top = topdom;
+    spin_unlock(&domid_lock);
+    do {
+        ++dom;
+        if (dom == top) {
+            dom = 1;
+        }
+        if (is_free_domid(dom)) goto exit;
+    } while (dom != cur);
+    /* Couldn't find a free domain id in 0..topdom, try higher. */
+    for (dom = top; dom < DOMID_SELF; dom++) {
+        if(is_free_domid(dom)) goto exit;
+    }
+    /* No free domain ids. */
+    err = -ENOMEM;
+  exit:
+    if (err == 0) {
+        spin_lock(&domid_lock);
+        curdom = dom;
+        if (dom >= topdom) {
+            topdom = dom + 1;
+        }
+        spin_unlock(&domid_lock);
+        *pdom = dom;
+    }
+    return err;
+}
+
+#if 0
+        struct domain    *d;
+        static domid_t    domnr = 0;
+        static spinlock_t domnr_lock = SPIN_LOCK_UNLOCKED;
+        unsigned int      pro;
+        domid_t           dom;
+
+        ret = -ENOMEM;
+
+        if(op->u.createdomain.domain > 0){
+            d = find_domain_by_id(dom);
+            if(d){
+                put_domain(d);
+                ret = -EINVAL;
+                break;
+            }
+        } else {
+            /* Search for an unused domain identifier. */
+            for ( ; ; )
+            {
+                spin_lock(&domnr_lock);
+                /* Wrap the roving counter when we reach first special value. */
+                if ( (dom = ++domnr) == DOMID_SELF )
+                    dom = domnr = 1;
+                spin_unlock(&domnr_lock);
+                
+                if ( (d = find_domain_by_id(dom)) == NULL )
+                    break;
+                put_domain(d);
+             }
+        }
+#endif
+
 long do_dom0_op(dom0_op_t *u_dom0_op)
 {
     long ret = 0;
@@ -101,25 +193,24 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     case DOM0_CREATEDOMAIN:
     {
         struct domain    *d;
-        static domid_t    domnr = 0;
-        static spinlock_t domnr_lock = SPIN_LOCK_UNLOCKED;
         unsigned int      pro;
         domid_t           dom;
 
         ret = -ENOMEM;
 
-        /* Search for an unused domain identifier. */
-        for ( ; ; )
+        dom = op->u.createdomain.domain;
+        if ( 0 < dom && dom < DOMID_SELF )
         {
-            spin_lock(&domnr_lock);
-            /* Wrap the roving counter when we reach first special value. */
-            if ( (dom = ++domnr) == DOMID_SELF )
-                dom = domnr = 1;
-            spin_unlock(&domnr_lock);
-
-            if ( (d = find_domain_by_id(dom)) == NULL )
+            if ( !is_free_domid(dom) )
+            {
+                ret = -EINVAL;
                 break;
-            put_domain(d);
+            }
+        }
+        else
+        {
+            ret = allocate_domid(&dom);
+            if ( ret ) break;
         }
 
         if ( op->u.createdomain.cpu == -1 )
index 9cb5656b3eaa037ae200d71d57286110e8817b75..502c14744d775fec5f9e0d47ac7637782a4fdcc7 100644 (file)
@@ -55,8 +55,10 @@ typedef struct {
     u8           name[MAX_DOMAIN_NAME]; /*  8 */
     u32          cpu;                 /* 24 */
     u32          __pad;               /* 28 */
-    /* OUT parameters. */
+    /* IN/OUT parameters. */
+    /* If 0, domain is allocated. If non-zero use it unless in use. */
     domid_t      domain;              /* 32 */
+    /* OUT parameters. */
 } PACKED dom0_createdomain_t; /* 36 bytes */
 
 #define DOM0_DESTROYDOMAIN     9